package com.xhs.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * @desc: CompletableFuture 异常回调案例
 * @projectName: java-tools-parent
 * @author: xhs
 * @date: 2025-08-09 周六 15:55
 */
@Slf4j
@RestController
@RequestMapping("/completableFutureExCallback")
public class CompletableFutureExCallbackController {

    /**
     * whenComplete 没有异常时
     */
    @GetMapping("/whenComplete")
    private void whenComplete() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            log.info("任务A线程：" + Thread.currentThread().getName());
            return "hello";
        }).whenComplete((result, throwable) -> {
            log.info("whenComplete线程：" + Thread.currentThread().getName());
            log.info("任务A执行结果：" + (Objects.isNull(result) ? "null" : result));
            log.info("任务A执行异常信息:" + (Objects.isNull(throwable) ? "null" : throwable.getMessage()));
        });
        log.info("最终返回的结果： " + future.get());
    }

    /**
     * 存在异常时 whenComplete执行完成后，返回的还是接收上一个任务的结果result
     */
    @GetMapping("/whenCompleteEx")
    private void whenCompleteEx() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            log.info("任务A线程：" + Thread.currentThread().getName());
            int i = 10 / 0;
            return "hello";
        }).whenComplete((result, throwable) -> {
            log.info("whenComplete线程：" + Thread.currentThread().getName());
            log.info("任务A执行结果：" + (Objects.isNull(result) ? "null" : result));
            log.info("任务A执行异常信息:" + (Objects.isNull(throwable) ? "null" : throwable.getMessage()));
        });
        log.info("最终返回的结果： " + future.get());
    }

    /**
     * whenComplete + exceptionally组合使用,
     * whenComplete没有返回值，直接抛出异常
     * exceptionally处理异常后，可以返回数据
     */
    @GetMapping("/exceptionally")
    private void exceptionally() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            log.info("任务A线程：" + Thread.currentThread().getName());
            int i = 10 / 0;
            return "hello";
        }).whenComplete((result, throwable) -> {
            log.info("whenComplete线程：" + Thread.currentThread().getName());
            log.info("任务A执行结果：" + (Objects.isNull(result) ? "null" : result));
            log.info("任务A执行异常信息:" + (Objects.isNull(throwable) ? "null" : throwable.getMessage()));
        }).exceptionally((e) -> {
            log.info("exceptionally中异常：" + e.getMessage());
            return "已经处理异常";
        });
        log.info("最终返回的结果： " + future.get());
    }

    /**
     * handle 可以接收异常和正常返回的结果，而且可以处理异常和结果，存在返回值
     */
    @GetMapping("/handle")
    private void handle() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            log.info("任务A线程：" + Thread.currentThread().getName());
            int i = 10 / 0;
            return "hello";
        }).handle((result, throwable) -> {
            log.info("whenComplete线程：" + Thread.currentThread().getName());
            log.info("任务A执行结果：" + (Objects.isNull(result) ? "null" : result));
            log.info("任务A执行异常信息:" + (Objects.isNull(throwable) ? "null" : throwable.getMessage()));
            return "handle处理后结果";
        });
        log.info("最终返回的结果： " + future.get());
    }
}
